<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>basic</title>
    <script src="js/three.js"></script>
    <script src="js/Stats.js"></script>
    <script src="js/dat.js"></script>
    <style>
        body {
            margin: 0;
            overflow: hidden;
        }
    </style>
</head>
<body>
<div id="WebGL-output"></div>
<div id="stats-output"></div>
</body>
<script>
    var stats = initStats();

    var scene = new THREE.Scene();
    // scene.fog = new THREE.FogExp2(0xffffff, 0.015)
    scene.fog = new THREE.Fog(0xffffff, 0.015, 100)

    var camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 1000)
    scene.add(camera)

    var renderer = new THREE.WebGLRenderer()
    renderer.setSize(window.innerWidth, window.innerHeight)
    renderer.setClearColor(new THREE.Color(0xEEEEEE, 1.0))
    renderer.shadowMap.enabled = true

    var planeGeometry = new THREE.PlaneGeometry(60, 40, 1, 1)
    var planeMaterial = new THREE.MeshLambertMaterial({color: 0xffffff})
    var plane = new THREE.Mesh(planeGeometry, planeMaterial)
    plane.receiveShadow = true
    plane.rotation.x = -0.5 * Math.PI
    plane.position.set(0, 0, 0)

    scene.add(plane)

    camera.position.set(-30, 40, 30)
    scene.add(camera)
    camera.lookAt(scene.position)

    var ambientLight = new THREE.AmbientLight(0x0c0c0c)
    scene.add(ambientLight)

    var spotLight = new THREE.SpotLight(0xffffff)
    spotLight.position.set(-40, 60, -10)
    spotLight.castShadow = true
    scene.add(spotLight)

    document.getElementById('WebGL-output').appendChild(renderer.domElement)

    var step = 0;
    var controls = new function () {
        this.rotationSpeed = 0.02;
        this.numberOfObjects = scene.children.length

        this.removeCube = function () {
            var allChilren = scene.children
            var lastObject = allChilren[allChilren.length - 1]
            if(lastObject instanceof THREE.Mesh) {
                scene.remove(lastObject)
                this.numberOfObjects = scene.children.length
            }
        }

        this.addCube = function () {
            var cubeSize = Math.ceil(Math.random() * 3)
            var cubeGeometry = new THREE.BoxGeometry(cubeSize, cubeSize, cubeSize)
            var cubeMaterial = new THREE.MeshLambertMaterial({color: Math.random() * 0xffffff})
            var cube = new THREE.Mesh(cubeGeometry, cubeMaterial)
            cube.castShadow = true
            cube.name = "cube-" + scene.children.length

            const randomX = -30 + Math.round(Math.random() * planeGeometry.parameters.width)
            const randomY = Math.round(Math.random() * 5)
            const randomZ = -20 + Math.round(Math.random() * planeGeometry.parameters.height);
            cube.position.set(randomX, randomY, randomZ)

            scene.add(cube)
            this.numberOfObjects = scene.children.length
        }

        this.outputObjects = function() {
            console.log(scene.children)
        }
    }


    var gui = new dat.GUI()
    gui.add(controls, 'rotationSpeed',0,0.5)
    gui.add(controls, 'addCube')
    gui.add(controls, 'removeCube')
    gui.add(controls, 'outputObjects')
    gui.add(controls, 'numberOfObjects').listen()

    render()

    function render() {
        stats.update()
        scene.traverse(function (e) {
            if(e instanceof THREE.Mesh && e !== plane) {
                e.rotation.x += controls.rotationSpeed
                e.rotation.y += controls.rotationSpeed
                e.rotation.z += controls.rotationSpeed
            }
        })
        requestAnimationFrame(render)
        renderer.render(scene, camera)
    }

    function initStats() {
        var stats = new Stats()

        stats.setMode(0)
        stats.domElement.style.position = 'absolute'
        stats.domElement.style.left = '0px'
        stats.domElement.style.top = '0px'
        document.getElementById('stats-output').appendChild(stats.domElement)
        return stats
    }
</script>
</html>